<template>
	<div class="input-container flex items-center">
		<template v-if="showIcon">
			<div @click="handleShow">
				<slot name="icon">
					<img src="/@/assets/map-icon-default.png" class="w-[21px] h-[30px]" />
				</slot>
			</div>
		</template>
		<template v-else>
			<el-input ref="inputMapRef" class="flex-1" clearable :value="address" :placeholder="placeholder" :disabled="disabled" @click="handleShow" />
			<el-button v-if="showRightBtn" class="ml-10" @click="handleShow">选择地址</el-button>
		</template>
	</div>
	<el-dialog v-model="dialogVisible" title="选择位置" width="60%" align-center @close="onDialogClose">
		<div class="flex items-center justify-between mb-4">
			<div class="search-container flex items-center">
				<div class="flex items-center mr-6 poi-box">
					<span class="mr-2">地址:</span>
					<el-input v-model="keyword" style="width: 240px" placeholder="请输入地址 如：成都" />
					<el-button type="primary" class="search-btn shrink-0" @click="mapSearchClick">
						<el-icon><Search /></el-icon>
					</el-button>
					<div v-show="showPoi" ref="poiRef" class="poi-container">
						<el-scrollbar class="h-[200px]">
							<div v-for="poi in poiList" :key="poi.id" class="poi-item" @click="selectPoi(poi)">
								<div class="poi-name">{{ poi.name }}</div>
								<div class="poi-address">
									{{ poi.address }}
								</div>
							</div>
						</el-scrollbar>
					</div>
				</div>
				<div class="flex items-center">
					<span class="mr-2">经纬度:</span>
					<el-input v-model="keyword2" style="width: 240px" placeholder="请输入经纬度 如：104.0664,30.6790" />
					<el-button type="primary" class="search-btn shrink-0" @click="mapSearchClick2">
						<el-icon><Search /></el-icon>
					</el-button>
				</div>
			</div>
		</div>
		<div id="input-map-container">loading</div>

		<template #footer>
			<span class="flex justify-end">
				<el-button v-if="!disabled" type="primary" @click="handleSubmit">确 定</el-button>
			</span>
		</template>
	</el-dialog>
</template>

<script setup lang="ts">
import { ref, shallowRef, nextTick, reactive, onUnmounted, watch } from 'vue';
import { loadAmap } from '/@/utils/mapLoad';
import { getAddress, searchPoi } from '/@/utils/mapUtils';
import { onClickOutside } from '@vueuse/core';
import { ElMessage, ElDialog, useFormItem } from 'element-plus';

defineOptions({
	name: 'InputMap',
});

const { formItem } = useFormItem();

const props = withDefaults(
	defineProps<{
		address?: string;
		position?: (number | string)[];
		disabled?: boolean;
		placeholder?: string;
		showRightBtn?: boolean;
		satus?: string;
		actindex?: number;
		showIcon?: boolean;
	}>(),
	{
		address: '',
		position: () => [],
		disabled: false,
		placeholder: '请选择地址',
		showRightBtn: false,
		satus: '',
		actindex: 0,
	}
);
const emits = defineEmits(['handle-finish']);

const locData = reactive({
	lon: '',
	lat: '',
	address: props.address || '',
	adcode: '',
	township: '',
	district: '',
});

watch(
	() => props.address,
	() => {
		locData.address = props.address;

		// 触发change事件
		formItem?.validate('change');
	}
);

const dialogVisible = ref(false);
const inputMapRef = shallowRef();
let map: any;
let marker: any;

onUnmounted(() => {
	if (map) map.destroy();
});

function initMap() {
	if (marker) marker.setMap(null);
	if (map) {
		if ((props.satus == '详情' || props.satus == '编辑') && props.position.length) {
			addMarker(props.position[0], props.position[1]);
		}
		return;
	}

	loadAmap().then(() => {
		map = new window.AMap.Map('input-map-container', {
			center: [104.066392, 30.572921],
		});
		map.addControl(new window.AMap.ToolBar());

		if ((props.satus == '详情' || props.satus == '编辑') && props.position.length) {
			keyword2.value = `${props.position[0]},${props.position[1]}`;
			addMarker(props.position[0], props.position[1]);
		}

		map.on('click', (e: any) => {
			if (props.disabled) return;
			if (props.satus == '详情') {
				return;
			}
			const lnglat = e.lnglat;
			const P = lnglat.getLat();
			const R = lnglat.getLng();
			keyword2.value = `${R},${P}`;
			addMarker(R, P);
			getAddress(R, P).then((aRsp) => {
				locData.address = aRsp.formattedAddress;
				locData.lon = String(aRsp.longitude);
				locData.lat = String(aRsp.latitude);
				locData.adcode = aRsp.addressComponent.adcode;
				locData.district = aRsp.addressComponent.district;
				locData.township = aRsp.addressComponent.township;
			});
		});
	});
}

// 添加坐标
function addMarker(R: number | string, P: number | string) {
	clearMarker();
	marker = new window.AMap.Marker({
		position: [R, P],
	});
	marker.setMap(map);
	map.setFitView(marker);
}
//清空坐标
function clearMarker() {
	if (marker) {
		marker.setMap(null);
		marker = null;
	}
}
// 显示弹出层
function handleShow() {
	dialogVisible.value = true;

	nextTick(() => {
		initMap();
	});
}
// 搜索经纬度
const keyword2 = ref('');
function mapSearchClick2() {
	if (keyword2.value) {
		let point = unref(keyword2).split(',');
		if (!isNaN(Number(point[0])) && !isNaN(Number(point[1]))) {
			selectPoi({ location: { lat: point[1], lng: point[0] } });
		} else {
			ElMessage.error('经纬度填写错误');
		}
	}
}
// 搜索poi
const keyword = ref('');
const poiList = ref<any>([]);
const showPoi = ref(false);
const poiRef = shallowRef();
onClickOutside(poiRef, () => {
	showPoi.value = false;
});
async function mapSearchClick() {
	try {
		poiList.value = await searchPoi(keyword.value);
		showPoi.value = true;
	} catch (err) {
		/* empty */
		showPoi.value = false;
		console.error(err);
	}
}
function selectPoi(poi: any) {
	const P = poi.location.lat;
	const R = poi.location.lng;
	addMarker(R, P);
	getAddress(R, P).then((aRsp) => {
		locData.address = aRsp.formattedAddress;
		locData.lon = String(aRsp.longitude);
		locData.lat = String(aRsp.latitude);
		locData.adcode = aRsp.addressComponent.adcode;
		locData.district = aRsp.addressComponent.district;
		locData.township = aRsp.addressComponent.township;
	});

	showPoi.value = false;
	poiList.value.length = 0;
	keyword.value = poi.name;
}
function handleSubmit() {
	if (props.satus == '详情') {
		dialogVisible.value = false;
		return;
	}
	if (!locData.lat && !locData.lon) {
		ElMessage.warning('未增加点位信息或未修改点位信息！！!');
		return;
	}
	dialogVisible.value = false;
	emits('handle-finish', locData, props.actindex);
}

function onDialogClose() {
	if (!props.showIcon) {
		inputMapRef.value.blur();
	}
	dialogVisible.value = false;
}
</script>

<style scoped lang="scss">
.input-container {
	width: 100%;
}

#input-map-container {
	height: 500px;
	cursor: pointer;
}
.poi-box {
	position: relative;
	.poi-container {
		position: absolute;
		top: 40px;
		left: 0px;
		width: 100%;
		height: 200px;
		background-color: #fff;
		overflow-y: auto;
		z-index: 2;
		box-shadow: 0 0 4px 4px rgba(0, 0, 0, 0.1);

		.poi-item {
			padding: 5px;
			border-bottom: 1px solid #f1f1f1;
			cursor: pointer;

			&:last-of-type {
				border-bottom: none;
			}
			&:hover {
				background-color: #eeeeee;
			}
		}
		.poi-name {
			font-size: 14px;
		}
		.poi-address {
			font-size: 12px;
		}
	}
}
/*.search-container {
      // width: 420px;
      height: 40px;
      background: #ffffff;
      // border-radius: 2px;
      // border: 1px solid #d6d6d6;
      position: relative;

      input {
        padding: 5px 10px;
        border: none;
        height: 38px;
        border-radius: 4px;
        box-sizing: border-box;
        font-size: 12px;
      }

      /~  .search-btn {
        width: 44px;
        height: 38px;
        border-radius: 2px;
        border: none;
        vertical-align: baseline;
      }~/

    }*/
</style>
